﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Office.Interop.Excel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using GemBox.Spreadsheet;
using GemBox.Spreadsheet.WinFormsUtilities;
using System.Text.RegularExpressions;
namespace Battleship
{
    public partial class MainForm : Form
    {
        System.Threading.Thread loadingThread;
        public static String waterLevel;
        LoadingPlan planning;
        string path = "";

        int regionNumber = 0;
        int regionsPerRow = 0;
        int rowNumber = 0;
        int containerSize = 30;
        Size regionSize = new Size(0, 0);
        System.Drawing.Point space = new System.Drawing.Point(0, 0);
        Region[] regionList = new Region[8];

        public MainForm()
        {
            InitializeComponent();
            GemBox.Spreadsheet.SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");

            planning = new LoadingPlan();

            regionNumber = 8;
            regionsPerRow = 4;
            regionSize.Width = 4;
            regionSize.Height = 5;

            rowNumber = regionNumber / regionsPerRow + (regionNumber % regionsPerRow == 0 ? 0 : 1);
            onClickEvent += new EventHandler(onClick);

            loadDataTank();
            loadStatictis();
        }

        private ContainerManager containerManager;

        public void initContainerManager()
        {
            containerManager = new ContainerManager(regionSize.Width, regionSize.Height, regionNumber);
            int index = 0;
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    for (int k = 0; k < 4; k++)
                    {

                        ContainerInfo containerInfo = planning.loadingSpace.content[i, j, k].container;
                        if (containerInfo != null)
                        {
                            if ((containerInfo.Size==40 && j%2==0) || (containerInfo.Size==20))
                            {
                                index++;
                                Position position = new Position(k, i, j);
                                int containerSize = 1;
                                if (containerInfo.Size == 40)
                                {
                                    containerSize = 2;
                                }
                                ContainerModel container = new ContainerModel(containerInfo.no.ToString(), typeToConType(containerInfo.Type), false, containerSize, false, position);
                                container.color = typeToColor(containerInfo.Type);
                                containerManager.put(container);
                            }
                        }
                    }
                }
            }
        }

        private void refreshRegions()
        {
            for (int depth = 0; depth < containerManager.depth; depth++)
            {
                Region region = regionList[depth];
                Container[,] buttons = region.buttons;

                foreach (Container button in buttons)
                {
                    Position position = (Position)button.Tag;
                    ContainerModel container = containerManager.get(position);
                    button.setContainerModel(container);
                }
            }
        }

        public void drawRegions()
        {
            pnlShip.Controls.Clear();

            int[][,] positions = containerManager.positions;

            for (int i = 0; i < rowNumber; i++)
            {
                for (int j = 0; j < regionsPerRow; j++)
                {
                    int index = i * regionsPerRow + j;
                    if (index >= containerManager.depth)
                    {
                        return;
                    }

                    Region region = new Region(containerManager, index, containerSize, onClickEvent);
                    regionList[index] = region;

                    int spaceX = (pnlShip.Width - (region.Width * regionsPerRow)) / (regionsPerRow + 1);
                    int spaceY = (pnlShip.Height - (region.Height * rowNumber)) / (rowNumber + 1);

                    System.Drawing.Point location = new System.Drawing.Point()
                    {
                        X = region.Width * j + spaceX * (j + 1),
                        Y = region.Height * i + spaceY * (i + 1)
                    };
                    region.Location = location;
                    this.pnlShip.Controls.Add(region);
                }
            }
        }

        private void higlightContainer(ContainerModel container)
        {
            if (container == null)
            {
                return;
            }

            Position position = container.position;
            for (int i = position.z; i < position.z + container.size; i++)
            {
                Container bnt = regionList[i].buttons[position.x, position.y];
                bnt.setHighLightState();
            }
        }

        private void onClick(object sender, EventArgs e)
        {
            // cheat
            //dataGridView.Rows[dataGridView.Rows.Count - 1].Selected = true;
            Container button = sender as Container;
            Position position = (Position)button.Tag;
            dataGridView.DefaultCellStyle.BackColor = Color.White;
            if (selectedButton == null)
            {
                ContainerModel container = containerManager.get(position);

                if (container != null)
                {
                    selectedButton = button;
                    higlightContainer(container);

                    // get containerinfo
                    ContainerInfo containerInfo = planning.getContainerInfo(container);
                    if (containerInfo!=null)
                    {
                        this.lbStatus.Text = "Container " + containerInfo.Name 
                                            + ", Type : "+containerInfo.Type
                                            + ", Size : "+containerInfo.Size+" ft"
                                            + ", POO : " + containerInfo.POO.PN
                                            + ", POD : " + containerInfo.POD.PN
                                            + ", Weight : " + containerInfo.Weight;
                        foreach (DataGridViewRow item in dataGridView.Rows)
                        {
                            string containerName = item.Cells[0].Value.ToString();
                            if (containerName==containerInfo.Name)
                            {
                                item.Selected = true;
                                item.DefaultCellStyle.BackColor = Color.LightGray;
                            }
                        }
                    }
                }
            }
            else
            {
                if (selectedButton != button)
                {
                    Position posA = (Position)selectedButton.Tag;

                    ContainerModel containerA = containerManager.get(posA);
                    ContainerModel containerB = containerManager.get(position);

                    if (containerA != containerB)
                    {
                        bool swapSuccess = containerManager.swap(posA, position);

                        if (swapSuccess==true)
                        {
                            this.lbStatus.Text = "Swap container at (" + posA.x.ToString() + " " + posA.y.ToString() + " " + posA.z.ToString()
                                                + ") to (" + position.x.ToString() + " " + position.y.ToString() + " " + position.z.ToString()+")";
                            //planning.swap(containerA, containerB);

                            // MOMENT UPDATE
                            Moment moment = planning.loadingSpace.valMoment();
                            lbMoment.Text = getLBMomentText(moment) + " | (m = " + Math.Round(planning.getM(), 2).ToString() + ")";

                        }
                        else
                        {
                            this.lbStatus.Text = "Swap FAIL";
                        }
                    }
                }

                selectedButton = null;
                refreshRegions();
            }
        }

        private Container selectedButton = null;

        private EventHandler onClickEvent;

        private void Form1_Load(object sender, EventArgs e)
        {
            lblTittle.Text = waterLevel;
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {

        }

        private void btnCallWaterMeasure_click(object sender, EventArgs e)
        {
            int quantity = 5;
            Size size = new Size(150, 120);

            for (int i = 0; i < quantity; i++)
            {
                System.Drawing.Point location = new System.Drawing.Point(10 * (i + 1) + i * size.Width, 10);
                WaterBucket waterBucket = new WaterBucket(location, size, 80, Color.RoyalBlue, Color.Purple);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void tabPage1_Click(object sender, EventArgs e)
        {

        }

        private void picBucket_Click(object sender, EventArgs e)
        {

        }

        private void btnCreateContainer_Click(object sender, EventArgs e)
        {
            ContainerGenerator containerGenerator = new ContainerGenerator(ref planning);
            containerGenerator.Show();
        }

        private void btnCreatePort_Click(object sender, EventArgs e)
        {
            PortGenerator portGenerator = new PortGenerator();
            portGenerator.Show();
        }

        private void pnlShip_Resize(object sender, EventArgs e)
        {
            if (containerManager == null)
            {
                return;
            }

            for (int i = 0; i < rowNumber; i++)
            {
                for (int j = 0; j < regionsPerRow; j++)
                {
                    int index = i * regionsPerRow + j;
                    if (index >= containerManager.depth)
                    {
                        return;
                    }

                    Region region = regionList[index];

                    int spaceX = (pnlShip.Width - (region.Width * regionsPerRow)) / (regionsPerRow + 1);
                    int spaceY = (pnlShip.Height - (region.Height * rowNumber)) / (rowNumber + 1);

                    System.Drawing.Point location = new System.Drawing.Point()
                    {
                        X = region.Width * j + spaceX * (j + 1),
                        Y = region.Height * i + spaceY * (i + 1)
                    };

                    region.Location = location;
                }
            }
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            path = "";
            OpenFileDialog openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                path = openFileDialog.FileName;
            }

            planning.filePath = path;
            dataGVShow();
            this.lbStatus.Text = "Reading file ...\n";
            loadingThread = new System.Threading.Thread(new System.Threading.ThreadStart(planningRun));
            loadingThread.Start();
            this.progressBar.Show();

            Thread statusThread = new System.Threading.Thread(new System.Threading.ThreadStart(statusChecking));
            statusThread.Start();
            this.lbStatus.Text = "Ready";

            
        }

        public void dataGVShow()
        {
            var workbook = ExcelFile.Load(path);

            // Export active worksheet to DataGridView.
            DataGridViewConverter.ExportToDataGridView(
                workbook.Worksheets.ActiveWorksheet,
                dataGridView,
                new ExportToDataGridViewOptions() { ColumnHeaders = true });

            // Import DataGridView back to active worksheet.
            DataGridViewConverter.ImportFromDataGridView(
                workbook.Worksheets.ActiveWorksheet,
                dataGridView,
                new ImportFromDataGridViewOptions() { ColumnHeaders = true });
        }

        public void planningRun()
        {
            if (lbStatus.InvokeRequired)
            {
                lbStatus.Invoke(new MethodInvoker(delegate {
                    this.lbStatus.Text = "Reading file ...";
                    planning.readFile(path);

                    this.lbStatus.Text = "Spliting list ...";
                    planning.splitList();

                    infoShowing();

                    // PUSH 4 ORD-CON INTO REF-ZONE
                    this.lbStatus.Text = "Loading REF container ...";
                    planning.fillFirstTier_REFZ();

                    // FILL THE REF-ZONE
                    planning.fill_REFZ();

                    // FILL THE DAN-ZONE
                    this.lbStatus.Text = "Loading DAN container ...";
                    planning.fill_DANZ();

                    // FILL THE ORD-ZONE
                    this.lbStatus.Text = "Loading ORD container ...";
                    planning.fill_ORDZ();

                    planning.fill_ORDZ_cont();

                    // PUSH EMPTY CONTAINER
                    this.lbStatus.Text = "Loading EMP container ...";
                    planning.push_EMP();

                    // PUSH CONTAINER 
                    planning.fill_DANZ();
                    planning.fill_REFZ();

                    planning.fillFirstTier_REFZ();
                    planning.fill_ORDZ();
                    planning.fill_ORDZ_cont();

                    planning.push_EMP();

                    // OPTIMIZE
                    planning.optimize();

                    // TOPDOWN
                    planning.topdown();

                    // MOMENT UPDATE
                    Moment moment = planning.loadingSpace.valMoment();
                    lbMoment.Text = getLBMomentText(moment) + " | (m = " + Math.Round(planning.getM(), 2).ToString() + ")";
                    planning.moment = moment;
                    // LOAD

                    // inhold / on deck
                    outInHold.Text = planning.getInHold().ToString();
                    outOnDeck.Text = planning.getOnDeck().ToString();
                    //initContainerManager();

                    loadStatictis();

                    initContainerManager();
                    drawRegions();

                    // enable btn
                    btnCreateContainer.Enabled = true;
                    btnCreatePort.Enabled = true;
                    button2.Enabled = true;
                }));
            }
        }

        public void statusChecking()
        {
            if (progressBar.InvokeRequired)
            {
                progressBar.Invoke(new MethodInvoker(delegate {
                    while (loadingThread.ThreadState == System.Threading.ThreadState.Running)
                    {
                        this.progressBar.Value = (this.progressBar.Value + 1) % 100;
                    }
                    this.progressBar.Value = 100;
                    this.progressBar.Hide();
                    this.lbStatus.Text = "Ready";
                }));
            }
        }

        public void infoShowing()
        {

            this.rtbListStatus.Text += "\nINFORMATION :\n\n";
            this.rtbListStatus.Text += "Type  \t\t(20ft)\t(40ft) \n";
            this.rtbListStatus.Text += "----------------------------------------------------------------------\n";
            //this.rtbListStatus.Text += "All : \t" + planning.containerList.Count + "\n";
            this.rtbListStatus.Text += "Ordinary \t\t " + planning.ORD_20_List.Count + "  \t" + planning.ORD_40_List.Count + "\n";
            this.rtbListStatus.Text += "Refrigerate \t " + planning.REF_20_List.Count + "  \t" + planning.REF_40_List.Count + "\n";
            this.rtbListStatus.Text += "Dangerous \t " + planning.DAN_20_List.Count + "  \t" + planning.DAN_40_List.Count + "\n";
            this.rtbListStatus.Text += "Empty \t\t " + planning.EMP_20_List.Count + "  \t" + planning.EMP_40_List.Count + "\n";
            this.rtbListStatus.Text += planning.checkRule();
        }

        private void btnMaximize_Click(object sender, EventArgs e)
        {
            DataGVMaximize dataGVM = new DataGVMaximize(path);
            dataGVM.Show();
        }

        private void btnSaveExcel_Click(object sender, EventArgs e)
        {
            var workbook = ExcelFile.Load(path);

            string savePath = "";
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.DefaultExt = "xlsx";
            saveFileDialog.FileName = "DataList";
            saveFileDialog.Filter = "Excel (*.xlsx)|*.xlsx|All files (*.*)|*.*";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                savePath = saveFileDialog.FileName;
            }
            workbook.Save(savePath);
        }

        public string getLBMomentText(Moment moment)
        {
            string result = "Moment |  Mx = " + Math.Round(moment.X, 2).ToString()
                                    + "  |  My = " + Math.Round(moment.Y, 2).ToString()
                                    + "  |  Mz = " + Math.Round(moment.Z, 2).ToString();
         
            return result;
        }

        public void drawContainerMap()
        {

        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            drawRegions();

            dataGridView.Rows[5].DefaultCellStyle.BackColor = Color.Blue;
        }

        public ContainerType typeToConType(string type)
        {
            switch (type)
            {
                case "ORD":
                    return ContainerType.ORD;
                case "EMP":
                    return ContainerType.EMP;
                case "DAN":
                    return ContainerType.DAN;
                case "REF":
                    return ContainerType.REF;
                default:
                    return ContainerType.ORD;
            }
        }

        public Color typeToColor(string type)
        {
            switch (type)
            {
                case "ORD":
                    return Color.LightSkyBlue;
                case "EMP":
                    return Color.LightSeaGreen;
                case "DAN":
                    return Color.LightPink;
                case "REF":
                    return Color.LightCoral;
                default:
                    return Color.Black;
            }
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            chart.draw();
        }

        private void loadDataTank()
        {
            // Create an unbound DataGridView by declaring a column count.
            dataTankView.ColumnCount = 8;
            dataTankView.ColumnHeadersVisible = true;

            // Set the column header style.
            DataGridViewCellStyle columnHeaderStyle = new DataGridViewCellStyle();

            columnHeaderStyle.BackColor = Color.Beige;
            dataTankView.ColumnHeadersDefaultCellStyle = columnHeaderStyle;

            // Set the column header names.
            dataTankView.Columns[0].Name = "Tank Name";
            dataTankView.Columns[1].Name = "Wght(T)";
            dataTankView.Columns[2].Name = "Vol(%)";
            dataTankView.Columns[3].Name = "Cap(T)";
            dataTankView.Columns[4].Name = "LCG(M)";
            dataTankView.Columns[5].Name = "VCG(M)";
            dataTankView.Columns[6].Name = "TCG(M)";
            dataTankView.Columns[7].Name = "FSM";

            // Populate the rows. 
            string[] row1 = new string[] { "Food", "0.00", "0.00",
            "0.100", "-30.320", "4.870", "0.00", "0" };
            string[] row2 = new string[] { "Fresh Water", "0.00", "0.00",
            "4.00", "-33.320", "3.1", "0.00", "0" };
            string[] row3 = new string[] { "Lubrication Oil", "0.00", "0.00", 
            "4.30", "-25.500", "3.00", "0.00", "0" };
            object[] rows = new object[] { row1, row2, row3 };

            foreach (string[] rowArray in rows)
            {
                dataTankView.Rows.Add(rowArray);
            }
        }

        StabilityChart chart;

        public void showLoadingDialog()
        {
            
        }

        private void loadStatictis()
        {
            // m1, m2, m3
            double m1 = Double.Parse(dataTankView.Rows[0].Cells["Wght(T)"].Value.ToString());
            double m2 = Double.Parse(dataTankView.Rows[1].Cells["Wght(T)"].Value.ToString());
            double m3 = Double.Parse(dataTankView.Rows[2].Cells["Wght(T)"].Value.ToString());
            
            //Mx, My, Mz
            double Mx = planning.moment.X;
            double My = planning.moment.Y;
            double Mz = planning.moment.Z;
            double m = planning.getM();

            if (m1 != 0 && m2 != 0 && m3 != 0 && Mx != 0 && My != 0 && Mz != 0 && m != 0)
            {
                VerticalBalance VB = new VerticalBalance(m1, m2, m3, Mx, My, Mz, m);

                // Chart panel
                chart = new StabilityChart(VB.getKG, staticChart, VB);
                chart.draw();

                // Displacement summary panel
                outDisplacement.Text = Math.Round(VB.Displacement, 2).ToString();
                outLightShip.Text = 473.3 + "";
                outTank.Text = (m1 + m2 + m3) + "";
                outFore.Text = Math.Round(VB.getTm, 2).ToString();
                outAft.Text = Math.Round(VB.getTl, 2).ToString();
                outMean.Text = Math.Round(VB.AverageDraft, 2).ToString();
                outTrim.Text = Math.Round(VB.DeltaT, 2).ToString();
                outMTC.Text = Math.Round(VB.getM_trim, 3).ToString();
                outTPC.Text = Math.Round(VB.getTPC, 2).ToString();
                outLCB.Text = Math.Round(VB.getLCB, 2).ToString();
                outLCF.Text = Math.Round(VB.getLCF, 2).ToString();
                outLCG.Text = Math.Round(VB.getLCG, 2).ToString();
                outHeeling.Text = Math.Round(My / (VB.Displacement * VB.getGM / 57.3), 2).ToString();

                outEquivalent.Text = Math.Round(VB.AverageDraft, 2).ToString();
                outRollingSec.Text = Math.Round(Constants.C * Constants.B / Math.Sqrt(VB.getGM), 2).ToString();

                // Dynamic Stability panel
                out0to30.Text = Math.Round(chart.getArea30(), 2).ToString();
                out0to40.Text = Math.Round(chart.getArea40(), 2).ToString();
                out30to40.Text = Math.Round(chart.getArea30to40(), 2).ToString();
                outGZat30.Text = Math.Round(chart.getGZat30(), 2).ToString();

                //Static Stability Panel
                outStaticKMT.Text = Math.Round(VB.getKB + VB.getBM, 2).ToString();
                outStaticKG.Text = Math.Round(VB.getKG, 2).ToString();
                outStaticGM.Text = Math.Round(VB.getKG + VB.getBM - VB.getKG, 2).ToString();
            }
        }     

        private void btnReportExport_Click(object sender, EventArgs e)
        {
            string path = Constants.REPORT_TEMPLATE_PATH;

            var workbook = ExcelFile.Load(path);

            var worksheet = workbook.Worksheets.ActiveWorksheet;

            for (int i = 0; i < 3; i++)
            {
                int row = i + 6;
                worksheet.Cells["A" + row].Value = dataTankView.Rows[i].Cells["Tank Name"].Value;
                worksheet.Cells["B" + row].Value = dataTankView.Rows[i].Cells["Wght(T)"].Value;
                worksheet.Cells["C" + row].Value = dataTankView.Rows[i].Cells["Vol(%)"].Value;
                worksheet.Cells["D" + row].Value = dataTankView.Rows[i].Cells["Cap(T)"].Value;
                worksheet.Cells["E" + row].Value = dataTankView.Rows[i].Cells["LCG(M)"].Value;
                worksheet.Cells["F" + row].Value = dataTankView.Rows[i].Cells["VCG(M)"].Value;
                worksheet.Cells["G" + row].Value = dataTankView.Rows[i].Cells["TCG(M)"].Value;
                worksheet.Cells["H" + row].Value = dataTankView.Rows[i].Cells["FSM"].Value;
            }
            worksheet.Cells["B17"].Value = double.Parse(outDisplacement.Text);
            worksheet.Cells["B18"].Value = double.Parse(outLightShip.Text);
            worksheet.Cells["B20"].Value = Math.Round(planning.getM(), 2);
            worksheet.Cells["B21"].Value = Int32.Parse(outInHold.Text);
            worksheet.Cells["B22"].Value = Int32.Parse(outOnDeck.Text);

            double m1 = Double.Parse(dataTankView.Rows[0].Cells["Wght(T)"].Value.ToString());
            double m2 = Double.Parse(dataTankView.Rows[1].Cells["Wght(T)"].Value.ToString());
            double m3 = Double.Parse(dataTankView.Rows[2].Cells["Wght(T)"].Value.ToString());
            worksheet.Cells["B10"].Value = m1 + m2 + m3;
            worksheet.Cells["B11"].Value = double.Parse(outLightShip.Text);
            worksheet.Cells["B23"].Value = m1 + m2 + m3;
            worksheet.Cells["B24"].Value = m1;
            worksheet.Cells["B25"].Value = m2;
            worksheet.Cells["B26"].Value = m3;

            worksheet.Cells["F20"].Value = double.Parse(out0to30.Text);
            worksheet.Cells["F21"].Value = double.Parse(out0to40.Text);
            worksheet.Cells["F22"].Value = double.Parse(out30to40.Text);
            worksheet.Cells["F23"].Value = double.Parse(outGZat30.Text);
            worksheet.Cells["F24"].Value = double.Parse(outMaxGZ.Text);
            worksheet.Cells["F25"].Value = double.Parse(outStaticGM.Text);

            // display safe coefficient
            // worksheet.Cells["F27"].Value = double.Parse(outStaticGM.Text);

            worksheet.Cells["C31"].Value = double.Parse(outEquivalent.Text);
            worksheet.Cells["C32"].Value = double.Parse(outFore.Text);
            worksheet.Cells["C33"].Value = double.Parse(outAft.Text);
            worksheet.Cells["C34"].Value = double.Parse(outMean.Text);
            worksheet.Cells["C36"].Value = double.Parse(outTrim.Text);
            worksheet.Cells["C37"].Value = double.Parse(outHeeling.Text);

            worksheet.Cells["G31"].Value = double.Parse(outTPC.Text);
            worksheet.Cells["G32"].Value = double.Parse(outLCB.Text);
            worksheet.Cells["G33"].Value = double.Parse(outLCF.Text);
            worksheet.Cells["G34"].Value = double.Parse(outMTC.Text);
            worksheet.Cells["G35"].Value = double.Parse(outLCG.Text);
            worksheet.Cells["G36"].Value = double.Parse(outStaticKMT.Text);
            //worksheet.Cells["G37"].Value = outVCG.Text;

            worksheet.Pictures.Add(Constants.CHART_IMAGE_PATH, "B40", "E49");
            
            string savePath = "";
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.DefaultExt = "xlsx";
            saveFileDialog.FileName = "Report";
            saveFileDialog.Filter = "Excel (*.xlsx)|*.xlsx|PDF (*.pdf)|*.pdf|All files (*.*)|*.*";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                savePath = saveFileDialog.FileName;
            }
            workbook.Save(savePath);
        }

        int currentIndex = 0;
        private void btnNextTank_Click(object sender, EventArgs e)
        {
            dataTankView.Rows[currentIndex].Selected = false;
            if (currentIndex < dataTankView.Rows.Count - 2)
            {
                dataTankView.Rows[++currentIndex].Cells[0].Selected = true;
            }
            else
            {
                currentIndex = 0;
                dataTankView.Rows[0].Cells[0].Selected = true;
            }
            handleDataContainerCellClick(dataTankView);
        }

        private void btnPreviousTank_Click(object sender, EventArgs e)
        {
            dataTankView.Rows[currentIndex].Selected = false;
            if (currentIndex > 0)
            {
                dataTankView.Rows[--currentIndex].Cells[0].Selected = true;
            }
            else
            {
                currentIndex = dataTankView.RowCount - 2;
                dataTankView.Rows[currentIndex].Cells[0].Selected = true;
            }
            handleDataContainerCellClick(dataTankView);
        }

        private void txtWeight_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                System.Windows.Forms.TextBox txt = sender as System.Windows.Forms.TextBox;
                handleWeightChange(txt);
            }
        }

        private void txtWeight_TextChanged(object sender, EventArgs e)
        {
            System.Windows.Forms.TextBox txt = sender as System.Windows.Forms.TextBox;
            dataTankView.CurrentRow.Cells["Wght(T)"].Value = txt.Text;
        }

        private void txtVolume_TextChanged(object sender, EventArgs e)
        {
            System.Windows.Forms.TextBox txt = sender as System.Windows.Forms.TextBox;
            dataTankView.CurrentRow.Cells["Vol(%)"].Value = txt.Text;
        }

        private void dataTankView_SelectionChanged(object sender, EventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            handleDataContainerCellClick(dgv);
        }

        private void dataTankView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            currentIndex = dgv.CurrentRow.Index;
            handleDataContainerCellClick(dgv);
        }

        private void handleDataContainerCellClick(DataGridView dgv) 
        {
            if (dgv == null)
                return;
            if (dgv.CurrentRow.Selected || dgv.CurrentCell.Selected)
            {
                txtCapacity.Text = dgv.CurrentRow.Cells["Cap(T)"].Value.ToString();
                txtWeight.Text = dgv.CurrentRow.Cells["Wght(T)"].Value.ToString();
                txtVolume.Text = dgv.CurrentRow.Cells["Vol(%)"].Value.ToString();
                txtLCG.Text = dgv.CurrentRow.Cells["LCG(M)"].Value.ToString();
                txtVCG.Text = dgv.CurrentRow.Cells["VCG(M)"].Value.ToString();
                txtTCG.Text = dgv.CurrentRow.Cells["TCG(M)"].Value.ToString();
                txtFSM.Text = dgv.CurrentRow.Cells["FSM"].Value.ToString();
            }
        }

        private void txtVolume_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                System.Windows.Forms.TextBox txt = sender as System.Windows.Forms.TextBox;
                if (txt.Text.Length > 0)
                {
                    try
                    {
                        dataTankView.CurrentRow.Cells["Vol(%)"].Value = txt.Text;
                        double vol = Double.Parse(txt.Text);
                        double cap = Double.Parse(dataTankView.CurrentRow.Cells["Cap(T)"].Value.ToString());
                        if (vol > 100)
                        {
                            txt.Text = 100 + "";
                            vol = 100;
                            MessageBox.Show("Thể tích bạn nhập vượt quá sức chứa, vui lòng nhập lại"
                            , "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        else
                        {
                            txtWeight.Text = Math.Round(vol * cap / 100, 2).ToString();
                            dataTankView.CurrentRow.Cells["Vol(%)"].Value = txtWeight.Text;
                            loadStatictis();
                        }
                        
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Định dạng số thể tích bạn nhập chưa đúng, vui lòng nhập lại"
                            , "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    string messageBoxText = "Bạn chưa nhập thể tích container";
                    string caption = "Cảnh báo";
                    MessageBox.Show(messageBoxText, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

        private void handleWeightChange(System.Windows.Forms.TextBox txt)
        {
            if (txt.Text.Length > 0)
            {
                try
                {
                    double weight = Double.Parse(txt.Text);
                    double cap = Double.Parse(dataTankView.CurrentRow.Cells["Cap(T)"].Value.ToString());
                    if (weight > cap)
                    {
                        txt.Text = cap.ToString();
                        weight = cap;
                        MessageBox.Show("Khối lượng bạn nhập vượt quá sức chứa, vui lòng nhập lại"
                        , "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        txtVolume.Text = Math.Round(((weight / cap) * 100), 2).ToString();
                        dataTankView.CurrentRow.Cells["Vol(%)"].Value = txtVolume.Text;
                        loadStatictis();
                    }
                }
                catch (FormatException)
                {
                    MessageBox.Show("Định dạng số khối lượng bạn nhập chưa đúng, vui lòng nhập lại"
                        , "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                string messageBoxText = "Bạn chưa nhập khối lượng container";
                string caption = "Cảnh báo";
                MessageBox.Show(messageBoxText, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnFullTank_Click(object sender, EventArgs e)
        {
            double weight = Double.Parse(txtCapacity.Text);
            txtWeight.Text = weight + "";
            handleWeightChange(txtWeight);
        }

        private void btnNullTank_Click(object sender, EventArgs e)
        {
            txtWeight.Text = "0";
            handleWeightChange(txtWeight);
        }

        private void txtWeight_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtWeight.SelectAll();
        }

        private void txtVolume_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtVolume.SelectAll();
        }

        private void loadingBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            loadStatictis();
        }

        private void loadingBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            StabilityProgressBar.Value = e.ProgressPercentage;
            displayProgress.Text = e.ProgressPercentage.ToString();
        }
    }
}
